package com.example.demo.utils;

import cn.hutool.core.date.DateUtil;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

/**
 * @author caiwenhong
 * @description:日期工具类
 * @date 2015年7月27日
 */
public class DateUtils {

    /**
     * 把时间戳 转为 Date日期
     * @param timestamp 时间戳
     * @return date 日期
     */
    public static Date timestamp2DateTime(Long timestamp) {
        Date date = null;
        if (timestamp != null) {
            date = new Date();
            date.setTime(timestamp);
            return date;
        }
        return date;
    }

    /**
     * 把 Date日期 转为 时间戳
     *
     * @param dateTime 日期
     * @return long型的 时间戳
     */
    public static Long dateTime2timestamp(Date dateTime) {
        Long longDate = null;
        if (dateTime != null) {
            return dateTime.getTime();
        }
        return longDate;
    }

    /**
     * 把  date日期  转为     字符串日期
     * caiwenhong add 传入 date类型日期，返回 字符串 日期格式
     *
     * @param type; 日期格式
     *              1:yyyy-MM-dd HH:mm:ss ,
     *              2:yyyy-MM-dd
     * @param date  date类型日期
     * @return 字符串 日期格式
     */
    public static String date2String(Date date, int type) {
        String format = "";
        if (type == 1) {
            format = "yyyy-MM-dd HH:mm:ss";
        } else if (type == 2) {
            format = "yyyy-MM-dd";
        } else if (type == 3) {
            format = "yyyyMMddHHmmss";
        } else if (type == 4) {
            format = "yyyyMMdd";
        } else if (type == 5) {
            format = "yyyy-MM-dd HH";
        } else if (type == 6) {
            format = "yyyy-MM";
        } else if (type == 7) {
            format = "yyyy/MM/dd";
        }else if (type == 8) {
            format = "yyyy";
        }
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        return sdf.format(date);
    }


    /**
     * 把 字符串格式 日期   转为    date 日期
     *
     * @param dateStr 字符串日期
     * @param type    为:
     *                1:yyyy-MM-dd HH:mm:ss
     *                2:yyyy-MM-dd
     *                3:yyyy-MM-dd HH:mm
     * @return date 日期
     */
    public static Date string2date(String dateStr, int type) {
        String dateFormat = "";
        if (type == 1) {
            dateFormat = "yyyy-MM-dd HH:mm:ss";
        } else if (type == 2) {
            dateFormat = "yyyy-MM-dd";
        } else if (type == 3) {
            dateFormat = "yyyy-MM-dd HH:mm";
        } else if (type == 4) {
            dateFormat = "yyyyMMddHHmmss";
        } else if (type == 5) {
            dateFormat = "yyyy-MM";
        } else if (type == 6) {
            dateFormat = "yyyy/MM/dd";
        }
        SimpleDateFormat format = new SimpleDateFormat(dateFormat);
        Date date = null;
        try {
            date = format.parse(dateStr);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return date;
    }


    /**
     * 判断 在 一个时间范围内 是否有效，如：在24小时内有效，或者 1分钟内有效
     *
     * @param timestamp  时间戳
     * @param type       1：小时 ，2：分钟
     * @param expireTime 过期时间（数字），如：1、2、3、4……
     * @return true:时间在这个范围内（没过期），false:超过了这个范围（已过期）
     */
    public static Boolean isInvalidScope(Long timestamp, int type, String expireTime) {
        Boolean bool = true;
        if (timestamp == null) {
            return bool;
        }
        Long expireDate = null;
        //如果是 小时，如 24小时
        if (type == 1) {
            //得到过期 日期
            expireDate = Long.valueOf(expireTime) * 60 * 60 * 1000 + timestamp;
        }
        //如果是分钟，如 10分钟
        else if (type == 2) {
            //得到过期 日期
            expireDate = Long.valueOf(expireTime) * 60 * 1000 + timestamp;
        }
        //说明 已过期了，当前时间 已超过了 过期时间
        if (System.currentTimeMillis() > expireDate) {
            bool = false;
        }
        return bool;
    }

    /**
     * 获取前d天的日期时间
     *
     * @param d 前d天的天数
     * @return 字符串类型的日期
     */
    public static String getBeforeDate(int d) {
        Date dNow = new Date(); // 当前时间
        Date dBefore = new Date();

        Calendar calendar = Calendar.getInstance(); // 得到日历
        calendar.setTime(dNow);// 把当前时间赋给日历
        calendar.add(Calendar.DAY_OF_MONTH, d); // 设置为前一天
        dBefore = calendar.getTime(); // 得到前一天的时间

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); // 设置时间格式
        String result = sdf.format(dBefore); // 格式化前n天
        return result;
    }


    /**
     * 获取前d天的日期时间
     *
     * @param d 前d天的天数
     * @return 字符串类型的日期
     */
    public static String getBeforeDate2(Date dNow,int d) {
      //  Date dNow = new Date(); // 当前时间
        Date dBefore = new Date();

        Calendar calendar = Calendar.getInstance(); // 得到日历
        calendar.setTime(dNow);// 把当前时间赋给日历
        calendar.add(Calendar.DAY_OF_MONTH, d); // 设置为前一天
        dBefore = calendar.getTime(); // 得到前一天的时间

        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd"); // 设置时间格式
        String result = sdf.format(dBefore); // 格式化前n天
        return result;
    }

    public static void main(String[] args) {
        String kk="20230525";
        Date date = DateUtil.parse(kk, "yyyyMMdd");
        String aa=getBeforeDate2(date,-2);
        System.out.println(aa);
    }


    /**
     * 获取前d个月 的日期时间
     *
     * @param d 前d个月的月份
     * @return Date类型的日期
     */
    public static Date getBeforeMonthDate(int d) {
        Calendar curr = Calendar.getInstance();
        curr.set(Calendar.MONTH, curr.get(Calendar.MONTH) - d);
        Date date = curr.getTime();
        return date;
    }

    /**
     * 2个日期是字符串的比较
     *
     * @param date1 日期1
     * @param date2 日期2
     * @param type  类型
     * @return 1：date1大于date2, -1:date1小于date2, 0:date1等于date2
     */
    public static int compareDateBy2Str(String date1, String date2, int type) {
        SimpleDateFormat df = null;
        if (type == 0) {
            df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        } else if (type == 1) {
            df = new SimpleDateFormat("yyyy-MM-dd");
        }
        try {
            Date dt1 = df.parse(date1);
            Date dt2 = df.parse(date2);
            if (dt1.getTime() > dt2.getTime()) {
                return 1;
            } else if (dt1.getTime() < dt2.getTime()) {
                return -1;
            } else {
                return 0;
            }
        } catch (Exception exception) {
            exception.printStackTrace();
        }
        return 0;
    }

    /**
     * 2个日期是日期类型的比较
     *
     * @param date1 日期1
     * @param date2 日期2
     * @return 1：date1大于date2, -1:date1小于date2, 0:date1等于date2
     */
    public static int compareDateBy2Date(Date date1, Date date2) {
        try {
            Date dt1 = date1;
            Date dt2 = date2;
            if (dt1.getTime() > dt2.getTime()) {
                return 1;
            } else if (dt1.getTime() < dt2.getTime()) {
                return -1;
            } else {
                return 0;
            }
        } catch (Exception exception) {
            exception.printStackTrace();
        }
        return 0;
    }


    /**
     * 得到本月的第一天
     *
     * @return
     */
    public static String getMonthFirstDay() {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.DAY_OF_MONTH, calendar
                .getActualMinimum(Calendar.DAY_OF_MONTH));

        return sdf.format(calendar.getTime());
    }

    /**
     * 得到本月的最后一天
     *
     * @return
     */

    public static String getMonthLastDay() {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.DAY_OF_MONTH, calendar
                .getActualMaximum(Calendar.DAY_OF_MONTH));
        return sdf.format(calendar.getTime());
    }


    /**
     * @param year  年份
     * @param month 月份
     * @return 当前月份的最后一天
     */
    public static String getLastDayOfMonth(int year, int month) {
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.YEAR, year);
        cal.set(Calendar.MONTH, month - 1);
        cal.set(Calendar.DAY_OF_MONTH, cal.getActualMaximum(Calendar.DATE));
        return new SimpleDateFormat("yyyy-MM-dd ").format(cal.getTime());
    }

    /**
     * @param year  年份
     * @param month 月份
     * @return 当前月份的第一天
     */
    public static String getFirstDayOfMonth(int year, int month) {
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.YEAR, year);
        cal.set(Calendar.MONTH, month - 1);
        cal.set(Calendar.DAY_OF_MONTH, cal.getMinimum(Calendar.DATE));
        return new SimpleDateFormat("yyyy-MM-dd ").format(cal.getTime());
    }


    public static boolean isValidDate(String str, int formatType) {
        boolean convertSuccess = true;

        String formatResult = "";
        if (formatType == 1) {
            formatResult = "yyyy-MM-dd HH:mm:ss";
        } else if (formatType == 2) {
            formatResult = "yyyy/MM/dd";
        } else if (formatType == 3) {
            formatResult = "yyyy-MM-dd";
        }
        // 指定日期格式为四位年/两位月份/两位日期，注意yyyy/MM/dd区分大小写；
        SimpleDateFormat format = new SimpleDateFormat(formatResult);
        try {
            // 设置lenient为false.
            // 否则SimpleDateFormat会比较宽松地验证日期，比如2007/02/29会被接受，并转换成2007/03/01
            format.setLenient(false);
            format.parse(str);
        } catch (ParseException e) {
            // e.printStackTrace();
            // 如果throw java.text.ParseException或者NullPointerException，就说明格式不对
            convertSuccess = false;
        }
        return convertSuccess;
    }


    /**
     * 计算两个日期之间相差的天数
     *
     * @param smdate 较小的时间
     * @param bdate  较大的时间
     * @return 相差天数
     * @throws ParseException
     */
    public static int daysBetween(Date smdate, Date bdate) throws ParseException {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        smdate = sdf.parse(sdf.format(smdate));
        bdate = sdf.parse(sdf.format(bdate));
        Calendar cal = Calendar.getInstance();
        cal.setTime(smdate);
        long time1 = cal.getTimeInMillis();
        cal.setTime(bdate);
        long time2 = cal.getTimeInMillis();
        long between_days = (time2 - time1) / (1000 * 3600 * 24);

        return Integer.parseInt(String.valueOf(between_days));
    }

    /**
     * 字符串的日期格式的计算
     */
    public static int daysBetween(String smdate, String bdate) throws ParseException {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Calendar cal = Calendar.getInstance();
        cal.setTime(sdf.parse(smdate));
        long time1 = cal.getTimeInMillis();
        cal.setTime(sdf.parse(bdate));
        long time2 = cal.getTimeInMillis();
        long between_days = (time2 - time1) / (1000 * 3600 * 24);

        return Integer.parseInt(String.valueOf(between_days));
    }

    /**
     * Java获取某个月的天数
     */
    public static int getDaysOfMonth(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
    }

    /**
     * 指定日期的下一天
     */
    public static Date getNextDay(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.DAY_OF_MONTH, +1);//+1今天的时间加一天
        date = calendar.getTime();
        return date;
    }

    /**
     * 指定日期的下一天(字符串)
     * yyyy-MM-dd
     */
    public static String getNextDayStr(String dateStr) {
        String result = "";
        Date date2 = string2date(dateStr, 2);
        Date date = getNextDay(date2);
        result = date2String(date, 2);
        return result;
    }

    /**
     * java 计算两个日期相差了几个月
     *
     * @param startDateStr 开始日期
     * @param endDateStr   结束日期
     */
    public static int months(String startDateStr, String endDateStr) {
        Calendar startTime = Calendar.getInstance();
        Calendar endTime = Calendar.getInstance();
        endTime.setTime(DateUtils.string2date(startDateStr, 5));
        startTime.setTime(DateUtils.string2date(endDateStr, 5));
        int result = endTime.get(Calendar.MONTH) - startTime.get(Calendar.MONTH);
        int month = (endTime.get(Calendar.YEAR) - startTime.get(Calendar.YEAR)) * 12;
        int monthCount = Math.abs(month + result);
        return monthCount;
    }

}
